grammar class2java;
options {
     //k=2;
     language=Java;
  }
  
program	:	class_head constpool;

class_head: CLASS  qualifiedName EXTENDS  qualifiedName  'minor'  VERSION COLON INTLITERAL MAJOR VERSION COLON INTLITERAL ;

constpool:	const_head (const_body)+ EOF;

const_head:CONSTANT POOL COLON;

const_body: CONST CONST_INDEX '=' const_type SEMI  ;
const_type
	:	consttype_method|consttype_string|consttype_class|consttype_field|consttype_asciz|consttype_nameandtype;
consttype_method 
	:	 'Method'   CONST_INDEX '.' CONST_INDEX;
consttype_string 
	:	 'String'  CONST_INDEX;
consttype_class 
	:	 'class'  CONST_INDEX;
consttype_field 
	:	 'Field'  CONST_INDEX '.' CONST_INDEX;
consttype_asciz 
	:	 'Asciz' '\t' (.*) ('\n'|'\r');
consttype_nameandtype 
	:	 'NameAndType' CONST_INDEX ':' CONST_INDEX;	


objName 
    :   IDENTIFIER
        ('.' IDENTIFIER)*
    ;




WS  
    :   (
             ' '

        |    '\t'
        |    '\u000D'
        |    '\u000A'        

        ) 
            {
                skip();
            }          
    ;

CLASS	:	'class';
EXTENDS	:	'extends';
MAJOR	:	'major';
VERSION	:	'version';
CONSTANT:	'Constant';
POOL	:	'pool';

CONST	:	'const';
CONST_INDEX:	'#'('0'..'9')+;


INTLITERAL
    :   IntegerNumber 
    ;
    
fragment
IntegerNumber
    :   '0' 
    |   '1'..'9' ('0'..'9')*    
    |   '0' ('0'..'7')+         
    |   HexPrefix HexDigit+        
    ;

fragment
HexPrefix
    :   '0x' | '0X'
    ;
        
fragment
HexDigit
    :   ('0'..'9'|'a'..'f'|'A'..'F')
    ;



COLON
    :   ':'
    ;

SEMI
    :   ';'
    ;


    
COMMENT
         @init{
            boolean isJavaDoc = false;
        }
    :   '/*'
            {
                if((char)input.LA(1) == '*'){
                    isJavaDoc = true;
                }
            }
        (options {greedy=false;} : . )* 
        '*/'
            {
                if(isJavaDoc==true){
                    $channel=HIDDEN;
                }else{
                    skip();
                }
            }
    ;

LINE_COMMENT
    :   '//' ~('\n'|'\r')*  ('\r\n' | '\r' | '\n') 
            {
                skip();
            }
    |   '//' ~('\n'|'\r')*     // a line comment could appear at the end of the file without CR/LF
            {
                skip();
            }
    ;   


IDENTIFIER
    :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;


